/*
 * Copyright (c) 2012 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.libermundi.theorcs.core.tapestry.mixins;

import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.tapestry5.BindingConstants;
import org.apache.tapestry5.ComponentEventCallback;
import org.apache.tapestry5.ComponentResources;
import org.apache.tapestry5.Field;
import org.apache.tapestry5.annotations.AfterRender;
import org.apache.tapestry5.annotations.Import;
import org.apache.tapestry5.annotations.InjectContainer;
import org.apache.tapestry5.annotations.OnEvent;
import org.apache.tapestry5.annotations.Parameter;
import org.apache.tapestry5.annotations.RequestParameter;
import org.apache.tapestry5.ioc.annotations.Inject;
import org.apache.tapestry5.json.JSONArray;
import org.apache.tapestry5.json.JSONLiteral;
import org.apache.tapestry5.json.JSONObject;
import org.apache.tapestry5.services.javascript.JavaScriptSupport;
import org.slf4j.Logger;

import com.google.common.base.Strings;

/**
 * @author Martin Papy
 *
 */
@Import(
	library={
			"${core.scripts}/jquery.fcbkcomplete.js",
			"${core.scripts}/jquery.fcbkcomplete.init.js"
	},
	stylesheet="${core.styles}/jquery.fcbkcomplete.css"
)
public class FCBKComplete {
	public static final String LOAD_DATA_EVENT="loaddatas"; 
	
	private static final String INTERNAL_EVENT_NAME="senddatas";
	
	private static final String PARAM_NAME="tag";
	
	@Inject
	private Logger _logger;
	
	@InjectContainer
	private Field _field;

	@Inject
	private JavaScriptSupport _jsSupport;
	
	@Inject
	private ComponentResources _resources;
	
	@Parameter(value="true",defaultPrefix=BindingConstants.LITERAL)
	private boolean _addonTab;

	@Parameter(value="10",defaultPrefix=BindingConstants.LITERAL)
	private int _maxitems;
	
	@Parameter(value="1",defaultPrefix=BindingConstants.LITERAL)
	private int _inputMinSize;
	
	@Parameter(value="10",defaultPrefix=BindingConstants.LITERAL)
	private int _height;
	
	@Parameter(value="true",defaultPrefix=BindingConstants.LITERAL)
	private boolean _cache;
	
	@Parameter(value="false",defaultPrefix=BindingConstants.LITERAL)
	private boolean _newel;
	
	@Parameter(value="",defaultPrefix=BindingConstants.LITERAL)
	private String _width;

	@Parameter(value="512",defaultPrefix=BindingConstants.LITERAL)
	private String _dropdownWidth;
	
	@Parameter(defaultPrefix=BindingConstants.LITERAL)
	private String _onCreate;
	
	@Parameter(value="true",defaultPrefix=BindingConstants.LITERAL)
	private boolean _filterSelected;
	
	@Parameter(value="core.fcbkcomplete.complete",defaultPrefix=BindingConstants.MESSAGE)
	private String _completeText;
	
	@Parameter(defaultPrefix=BindingConstants.MESSAGE,allowNull=true)
	private String _selectAllText;
	
	@Parameter(defaultPrefix=BindingConstants.MESSAGE,allowNull=true)
	private String _placeHolder;
	
	@AfterRender
	public void afterRender() {
		JSONObject params = new JSONObject();
		
		params.put("selector", "#" + _field.getClientId())
			.put("eventUrl", _resources.createEventLink(INTERNAL_EVENT_NAME).toAbsoluteURI())
			.put("addontab", _addonTab)
			.put("maxitems", _maxitems)
			.put("input_min_size", _inputMinSize)
			.put("height", _height)
			.put("cache", _cache)
			.put("newel", _newel)
			.put("width", _width)
			.put("dropdownWidth", _dropdownWidth)
			.put("filter_selected",_filterSelected)
			.put("complete_text",_completeText)
			.put("select_all_text", _selectAllText)
			.put("input_placeholder", _placeHolder);
		
		if(!Strings.isNullOrEmpty(_onCreate)){
			params.put("oncreate", new JSONLiteral(_onCreate));
		}
		
		_jsSupport.addInitializerCall("initFCBKComplete", params);
	}
	
    @OnEvent(INTERNAL_EVENT_NAME)
    public JSONArray onUserInput(@RequestParameter(PARAM_NAME) String input) {
    	final JSONArray response = new JSONArray();

        ComponentEventCallback<Map<String, String>> callback = new ComponentEventCallback<Map<String, String>>() {
            @Override
			public boolean handleResult(Map<String, String> result) {
            	Iterator<Entry<String,String>> options = result.entrySet().iterator();
            	while(options.hasNext()) {
            		Entry<String, String> option = options.next();
            		response.put(new JSONObject("key",option.getKey(),"value",option.getValue()));
				}
                return true;
            }
        };

        _resources.triggerEvent(FCBKComplete.LOAD_DATA_EVENT, new Object[]{ input }, callback);
        
        if(_logger.isDebugEnabled()) {
        	_logger.debug("Input : " + input);
        	_logger.debug("Result : " + response.toString());
        }

        return response;
    }	
	
}
